#include "Jeu.h"
#include <stdio.h>


void JeuInitialise (Jeu ** jeu)
{
    *jeu = (Jeu*)malloc(sizeof(Jeu));
    GrilleInitialise(&((*jeu)->grille), DIMX, DIMY);
    LigneInitialise(&((*jeu)->ligne), &((*jeu)->grille));
}


const Grille * JeuGetConstGrille (const Jeu * jeu)
{
    return &(jeu->grille);
}


Grille * JeuGetGrille (Jeu * jeu)
{
    return &(jeu->grille);
}


int JeuGetJoueur ( Jeu * jeu)
{
    return jeu->joueurCourant;
}


void JeuSetJoueur (Jeu * jeu)
{
    jeu->joueurCourant = JoueurSuivant(jeu->joueurCourant);
}


Ligne * JeuGetLigne (Jeu * jeu)
{
    return &(jeu->ligne);
}


int CoupJouable (const int ColonneSaisie, const Grille * grille)
{
    if ((0<=ColonneSaisie) && (ColonneSaisie<=(grille->dimY)))
    {
        int i;
        for (i=0; i <= ColonneSaisie; i++)
        {
            if ( GetGrilleXY(grille, i, ColonneSaisie) == '*')
                /* teste s'il y a une case de libre dans la colonne saisie */
            {
                return 1 ;
            }
        }
    }
    return 0 ;
}


int Gagnant (const Grille * grille)
{
    if (LigneGagnante (grille) == 1 ||	ColonneGagnante (grille) == 1
            || DiagonaleDescendanteGagnante (grille) == 1 || DiagonaleMontanteGagnante (grille) == 1 )
    {
        return 1;
    }
    return 0;
}


int LigneGagnante (const Grille * grille)
{
    int i, j;
    for (i = 0; i < GetDimX(grille); i++)
    {
        for (j = 0; j < GetDimY(grille)-3; j++)
        {
            if (((GetGrilleXY(grille, i, j) == 'O') || GetGrilleXY(grille, i, j) == 'X')
                    && (GetGrilleXY(grille, i, j) == GetGrilleXY(grille, i, j+1))
                    && (GetGrilleXY(grille, i, j)== GetGrilleXY(grille, i, j+2))
                    && (GetGrilleXY(grille, i, j) == GetGrilleXY(grille, i,j+3)))
            {
                return 1;
            }
        }
    }
    return 0;
}


int ColonneGagnante (const Grille * grille)
{
    int i, j;
    for (i = 0; i < GetDimX(grille)-3; i++)
    {
        for (j = 0; j < GetDimY(grille); j++)
        {
            if ( ((GetGrilleXY(grille, i, j)== 'X') || (GetGrilleXY(grille, i, j) == 'O'))
                    &&
                    (GetGrilleXY(grille, i, j) == GetGrilleXY(grille, i+1, j)) &&
                    (GetGrilleXY(grille, i, j) == GetGrilleXY(grille, i+2, j)) &&
                    (GetGrilleXY(grille, i, j) == GetGrilleXY(grille, i+3, j)))
            {
                return 1;
            }
        }
    }
    return 0;
}


int DiagonaleDescendanteGagnante (const Grille * grille)
{
    int i, j;
    for (i = 0; i < GetDimX(grille) - 3; i++)
    {
        for (j = 0; j < GetDimY(grille) - 3; j++)
        {
            if ( ((GetGrilleXY(grille, i, j) == 'X')|| GetGrilleXY(grille, i, j) == 'O')
                    &&
                    (GetGrilleXY(grille, i, j) == GetGrilleXY(grille, i+1, j+1)) &&
                    (GetGrilleXY(grille, i, j) == GetGrilleXY(grille, i+2, j+2)) &&
                    (GetGrilleXY(grille, i, j) == GetGrilleXY(grille, i+3, j+3)) )
            {
                return 1;
            }
        }
    }
    return 0;
}



int DiagonaleMontanteGagnante (const Grille * grille)
{
    int i, j;
    for (i = 0; i < GetDimX(grille) - 3; i++)
    {
        for (j = 0; j < GetDimY(grille)- 3; j++)
        {
            if ( ((GetGrilleXY(grille, i, j) == 'X') || (GetGrilleXY(grille, i, j) == 'O'))
                    &&
                    (GetGrilleXY(grille, i, j+3) == GetGrilleXY(grille, i+1, j+2)) &&
                    (GetGrilleXY(grille, i, j) == GetGrilleXY(grille, i+2, j+1)) &&
                    (GetGrilleXY(grille, i, j) == GetGrilleXY(grille, i+3, j)) )
            {
                return 1;
            }
        }
    }
    return 0;
}


int JeuFini (const Jeu * jeu)
{
    if ((Gagnant(JeuGetConstGrille(jeu)) == 1) || (GrilleRemplie(JeuGetConstGrille(jeu)) == 1))
    {
        return 1;
    }
    return 0;
}


void JeuActionClavier(Jeu * jeu, const char direction)
{
    if ((direction == 'd') || (direction == 'g'))
    {
        LigneModifie(JeuGetLigne(jeu), direction);
    }
    if (direction == 'e')
    {
	if (GrilleLigneMin (&(jeu->grille), PionGetX(jeu->ligne.pion)) > - 1)
	{       

 PionPoseDansGrille(JeuGetGrille(jeu), jeu->ligne.pion, jeu->joueurCourant);
        JeuSetJoueur(jeu);
}
    }
}


void JeuBoucle (Jeu * jeu)
{
    while (JeuFini(jeu) != 1)
    {
        while (CoupJouable(jeu->ligne.pion->coordX, &(jeu->grille)) != 1)
        {
            AffichePionDansLigne(&(jeu->ligne));
        }
        PionPoseDansGrille(JeuGetGrille(jeu), jeu->ligne.pion, jeu->joueurCourant);
        JeuSetJoueur(jeu);
    }
}



void JeuAffiche (Jeu * jeu)
{
    AffichePionDansLigne(&(jeu->ligne));
    fprintf(stderr,"\n\n");
    GrilleAffiche(&(jeu->grille));
}


void JeuEfface(Jeu * jeu)
{
    jeu->joueurCourant = 0;
    free(jeu);
}
